#include"zigbeenode.h"
#include"edge.h"
#include<QTimer>
#include <QDebug>

ZigBeeNode::ZigBeeNode(const Node &N, const QPoint &position, QGraphicsScene *scene):/*QObject(),QGraphicsItem()*/QGraphicsObject()
  ,Nodestate(true),
    m_node(N),
    p_parent(NULL)
{
    setFlag(ItemIsMovable);
    setFlag(ItemSendsGeometryChanges);
    setFlag(ItemIsSelectable);
    Devicetype = N.getDescription();
    setPos(position);


    scene->clearSelection();
    scene->addItem(this);
    setSelected(true);
    setZValue(-1);


}


void ZigBeeNode::addEdge(Edge *edge)
{
    edgeList << edge;
    edge->adjust();
}

QList<Edge *>& ZigBeeNode::edges()
{
    return edgeList;
}


void ZigBeeNode::calculateForces()
{
    if (!scene() || scene()->mouseGrabberItem() == this) {
        newPos = pos();
        return;
    }

    // Sum up all forces pushing this item away
    qreal xvel = 0;
    qreal yvel = 0;
    foreach (QGraphicsItem *item, scene()->items()) {
        ZigBeeNode *node = qgraphicsitem_cast<ZigBeeNode *>(item);
        if (!node)
            continue;

        QPointF vec = mapToItem(node, 0, 0);
        qreal dx = vec.x();
        qreal dy = vec.y();
        double l = 2.0 * (dx * dx + dy * dy);
        if (l > 0) {
            xvel += (dx * 150.0) / l;
            yvel += (dy * 150.0) / l;
        }
    }

    // Now subtract all forces pulling items together
    double weight = (edgeList.size() + 1) * 10;
    foreach (Edge *edge, edgeList) {
        QPointF vec;
        if (edge->sourceNode() == this)
            vec = mapToItem(edge->destNode(), 0, 0);
        else
            vec = mapToItem(edge->sourceNode(), 0, 0);
        xvel -= vec.x() / weight;
        yvel -= vec.y() / weight;
    }

    if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1)
        xvel = yvel = 0;

    QRectF sceneRect = scene()->sceneRect();
    newPos = pos() + QPointF(xvel, yvel);
    newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10));
    newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10));
}

bool ZigBeeNode::advance()
{
    if (newPos == pos())
        return false;

    setPos(newPos);
    return true;
}
QRectF ZigBeeNode::boundingRect() const
{
    qreal adjust = 2;
    return QRectF(-10 - adjust, -10 - adjust,
                  23 + adjust, 23 + adjust);
}

QPainterPath ZigBeeNode::shape() const
{
    QPainterPath path;
    path.addEllipse(-10, -10, 20, 20);
    return path;
}
QVariant ZigBeeNode::itemChange(GraphicsItemChange change, const QVariant &value)
{
    switch (change) {
    case ItemPositionHasChanged:
        foreach (Edge *edge, edgeList)
            edge->adjust();
        //scene->itemMoved();
        break;
    default:
        break;
    };

    return QGraphicsItem::itemChange(change, value);
}
void ZigBeeNode::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget *)
{
    painter->setPen(Qt::NoPen);

    switch(Devicetype){
    case Coordinator:{
        if(Nodestate)
            painter->setBrush(Qt::blue);
        else
            painter->setBrush(Qt::darkGray);
        painter->drawEllipse(-12, -12, 26, 26);
        break;
    }

    case Router:{
        if(Nodestate)
            painter->setBrush(Qt::red);
        else
            painter->setBrush(Qt::darkGray);

        painter->drawEllipse(-12, -12, 20, 20);

        break;
    }
    case EndDevice:{
        if(Nodestate)
            painter->setBrush(Qt::green);
        else
            painter->setBrush(Qt::darkGray);
        painter->drawEllipse(-12, -12, 15, 15);




        break;
    }

    default:break;
    }

}

void ZigBeeNode::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    // update();
    QGraphicsItem::mousePressEvent(event);
}
void ZigBeeNode::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    //update();
    QGraphicsItem::mouseReleaseEvent(event);
}
void ZigBeeNode::changeStatus(bool status)
{
    //    qDebug() << trUtf8("节点状态改变") << status;


    //    if (m_node.getDescription() == Coordinator) {
    //        //根据状态重绘他们的颜色

    //    } else {
    //        if (m_node.getDescription() == Router) {

    //        } else {

    //        }
    //    }
    Nodestate = status;
    this->update();
}

void ZigBeeNode::setParentNode(ZigBeeNode *node)
{
    p_parent = node;
}
void ZigBeeNode::deleteParentEdge()
{
    if (p_parent == NULL) return;
    foreach (Edge* e,edgeList) {
        p_parent->deleteAedge(e);
    }

}
void ZigBeeNode::clearEdgeList()
{
    edgeList.clear();
}
void ZigBeeNode::deleteAedge(Edge *ed)
{
    edgeList.removeOne(ed);
}
